// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Z [author] rhyme_lph
// H [email]  rhymelph@gmail.com
// M [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/business_contact_entity.dart';
import 'package:finance_app/src/http_service/http_contact_service.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/widgets/bottom_sheet/delete_info_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';

import 'all_contacts_provider.dart';
import 'main_business_contact_provider.dart';

class DeleteBusinessContactProvider
    extends BaseProvider<List<BusinessContactEntity>>
    with
        SearchDataListMixin,
        RefreshMixin<List<BusinessContactEntity>, List<BusinessContactEntity>>,
        FormatGroupMapLocalMixin<BusinessContactEntity> {
  BusinessContactEntity deleteContact;

  @override
  Future get dataFuture => HttpContactService.contactList(1);

  void unFocus() {
    searchFocusNode.unfocus();
  }

  void onCancel() {
    obtainContext?.call((context) {
      Navigator.of(context).pop();
    });
  }

  @override
  FutureOr<List<BusinessContactEntity>> transformData(
      List<BusinessContactEntity> d, bool isCache) {
    contactToMap(d);
    return d;
  }

  void contactToMap(List<BusinessContactEntity> contacts) {
    groupMap.clear();
    sortGroupToMap(contacts,
        sort: (a, b) => sortNameFirst(a, b, (t) => t.name),
        group: (a) => groupFirstName(a, (t) => t.name, '*'),
        itemBefore: (map, b) => favoriteBefore(map, b, (b) => b.isFavorite));
    if (groupMap['Favourites'] != null && groupMap['Favourites'].length == 0) {
      groupMap.remove('Favourites');
    }
  }

  void onSelectBusinessContact(BusinessContactEntity data) {
    unFocus();
    deleteContact = data;
    update();
  }

  void onDeleteDone() {
    unFocus();
    if (deleteContact == null) {
      showToast(S.current.please_select_contact);
      return;
    }
    obtainContext?.call((context) async {
      bool isSuccess = await showDeleteContactInfoBottomSheet(context);

      if (isSuccess == true) {
        isSuccess = false;
        String msgError;
        await post(HttpContactService.deleteContact(deleteContact.id),
            loadingTip: S.current.loading, onSuccess: (result) {
          isSuccess = true;
        }, onError: (int code, String msg, _, __) {
          msgError = msg;
        });
        if (isSuccess == true) {
          await showContactSuccessBottomSheet(context);
          data.remove(deleteContact);
          transformData(data, false);
          update();
          final provider = Providers.get<MainBusinessContactProvider>(
              RouterGenProviders.mainBusinessContactPage, null);
          if (provider != null) {
            provider.onDeleteContact(deleteContact.id);
          }
          final allProvider = Providers.get<AllContactsProvider>(
              RouterGenProviders.allContactsPage, null);
          if (allProvider != null) {
            allProvider.onDeleteContact(deleteContact.id);
          }
          deleteContact = null;
          onCancel();
        } else {
          obtainContext?.call((context) {
            showGotItTipBottomSheet(context, msgError);
          });
        }
        // await showContactDueLinkedTransactionBottomSheet(context);
      }
    });
  }

  @override
  List<BusinessContactEntity> get dataList => data;

  @override
  List<BusinessContactEntity> getFromRequestResult(
      Response<dynamic> result, bool isRefresh) {
    List<BusinessContactEntity> resultData =
        getEntityFromResult<List<BusinessContactEntity>>(result);
    contactToMap(resultData);
    return resultData;
  }

  @override
  Future get refreshFuture => dataFuture;

  @override
  void searchRefreshData(data) {
    contactToMap(dataList);
    update();
  }

  @override
  void sortUpdate() {
    contactToMap(dataList);
  }

  @override
  void onRequestRefresh() {
    contactToMap(dataList);
  }

  void onClickStar(BusinessContactEntity e) async {
    bool isSuccess = false;
    await post(
        HttpContactService.updateContact(e.id,
            is_favorite: e.isFavorite == 1 ? 0 : 1),
        autoHandler: AutoHandler.Toast,
        loadingTip: S.current.loading, onSuccess: (result) {
      isSuccess = true;
    });
    if (isSuccess == true) {
      e.isFavorite = e.isFavorite == 1 ? 0 : 1;
      contactToMap(dataList);
      update();
    }
  }

  void updateContact(BusinessContactEntity entity) {
    final updateData = dataList.firstWhere((element) => element.id == entity.id,
        orElse: () => null);
    if (updateData != null) {
      updateData.fromJson(entity.toJson());
      contactToMap(dataList);
      update();
    } else {
      dataList.add(entity);
      contactToMap(dataList);
      update();
    }
  }
}
